package com.serial.comm.modular.serialPort.listener;


import com.alibaba.fastjson.JSON;
import com.serial.comm.config.rabbitmq.SerialMsgSender;
import com.serial.comm.config.redis.RedisService;
import com.serial.comm.core.constants.SerialConst;
import com.serial.comm.core.exception.ReadDataFromSerialPortFailure;
import com.serial.comm.core.exception.SerialPortInputStreamCloseFailure;
import com.serial.comm.core.exception.enums.ResponseCodeEnum;
import com.serial.comm.core.utils.SerialUtils;
import com.serial.comm.core.utils.StringUtils;
import com.serial.comm.modular.serialPort.model.TelegramMQ;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import purejavacomm.SerialPort;
import purejavacomm.SerialPortEvent;
import purejavacomm.SerialPortEventListener;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * 串口读取消息监听器
 */
@Component
public class SerialReadListener implements SerialPortEventListener {


    public static Logger log = LoggerFactory.getLogger(SerialReadListener.class);

    @Resource
    private SerialMsgSender serialMsgSender;

    @Resource
    private RedisService redisService;


    public static SerialReadListener serialReadListener;

    @PostConstruct
    public void init() {
        serialReadListener = this;
    }

    /**
     * 串口对象
     */
    private SerialPort serialPort;

    /**
     * 构建串口监听对象
     *
     * @param serialPort
     */
    public static SerialReadListener initSerialPort(SerialPort serialPort) {
        SerialReadListener listener = new SerialReadListener();
        listener.serialPort = serialPort;
        log.info(SerialConst.SysMessage.LISTENER_READY);
        return listener;
    }

    @Override
    public void serialEvent(SerialPortEvent serialPortEvent) {

        switch (serialPortEvent.getEventType()) {
            // 10 通讯中断
            case SerialPortEvent.BI:
                log.error(SerialConst.SysMessage.CONNECTION_INTERRUPT);
                break;

            case SerialPortEvent.OE: // 7 溢位（溢出）错误
                log.error(">>>>>>溢位（溢出）错误");
            case SerialPortEvent.FE: // 9 帧错误
                log.error(">>>>>>帧错误");
            case SerialPortEvent.PE: // 8 奇偶校验错误
                log.error(">>>>>>奇偶校验错误");
            case SerialPortEvent.CD: // 6 载波检测
                log.info(">>>>>>载波检测");
            case SerialPortEvent.CTS: // 3 清除待发送数据
                log.info(">>>>>>清除待发送数据");
            case SerialPortEvent.DSR: // 4 待发送数据准备好了
                log.info(">>>>>>待发送数据准备好了");
            case SerialPortEvent.RI: // 5 振铃指示
                log.info(">>>>>>振铃指示");
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
                log.info(">>>>>>输出缓冲区已清空");
                break;

            case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
                String dataOriginal;

                try {
                    //校验 1 串口是否依然存在
                    if (serialPort == null) {
                        log.error(SerialConst.SysMessage.SERIAL_PORT_IS_EMPTY);
                        return;
                    }

                    dataOriginal = SerialUtils.readFromPort(serialPort);

                    //校验 2 数据读取是否为空
                    if (StringUtils.isEmpty(dataOriginal)) {
                        log.error(SerialConst.SysMessage.NOVALID_DATA_PLEASE_CHECK);
                        return;
                    }
                    //发送到读取队列，在队列消费者中进行数据提取
                    TelegramMQ telegramMQ = new TelegramMQ(dataOriginal);
                    serialReadListener.serialMsgSender.sendReadBaseQueueMsg(JSON.toJSONString(telegramMQ));
                } catch (ReadDataFromSerialPortFailure e) {
                    throw new ReadDataFromSerialPortFailure(ResponseCodeEnum.READ_DATA_FROM_SERIAL_PORT_FAILURE);
                } catch (SerialPortInputStreamCloseFailure e) {
                    throw new SerialPortInputStreamCloseFailure(ResponseCodeEnum.SERIAL_PORT_INPUTSTREAM_CLOSE_FAILURE);
                }
                break;

        }

    }

}
